/*****************************************************************//**
 * \file   SurgicalRobotCamera.cpp
 * \brief  摄像头读取数据类
 * 
 * \author Administrator
 * \date   July 2021
 * \modify by Administrator
 * \date   July 2021

 *********************************************************************/
#include "./include/SurgicalRobotCamera.h"
#include "./include/SurgicalRobotCommon.h"
//#include <windows.h>
//#include <qDebug>
/**
 * \brief   SurgicalRobotCamera类构造函数.
 * 
 */
SurgicalRobotCamera::SurgicalRobotCamera()
{

}

/**
 * \brief   SurgicalRobotCamera析构函数.
 * 
 */
SurgicalRobotCamera::~SurgicalRobotCamera()
{
	camera.close();
}

/**
 * \brief       打开摄像头.
 * 
 * \param index 摄像头编号
 * \return      true表示成功，false表示失败
 */
bool SurgicalRobotCamera::open(int index)
{
	if (camera.open(index)) 
	{
		return true;
	}
	else {
		return false;
	}
}

/**
 * \brief   关闭摄像头.
 * 
 */
void SurgicalRobotCamera::close()
{
	camera.close();

	return;
}

/**
 * \brief   读取摄像头数据.
 * 
 * \return 读取的摄像头数据frame
 */
cv::Mat SurgicalRobotCamera::read()
{
	cv::Mat mat;

	mat = camera.read();

	return mat;
}

/**
 * \brief   读取并通知上层界面跟新图像显示.
 * 
 * \param index 摄像头编号
 */
// void setThreadAffinity(int cpu) {
//     cpu_set_t cpuset;
//     CPU_ZERO(&cpuset);
//     CPU_SET(cpu, &cpuset);

//     pthread_t currentThread = pthread_self();  // 获取当前线程

//     int result = pthread_setaffinity_np(currentThread, sizeof(cpu_set_t), &cpuset);
//     if (result != 0) {
//         perror("pthread_setaffinity_np");
//     }
// }

// void setThreadAffinity(int cpu) {
//     cpu_set_t cpuset;
//     CPU_ZERO(&cpuset);
//     CPU_SET(cpu, &cpuset);

//     // 获取当前线程的句柄
//     pthread_t currentThread = pthread_self();

//     // 设置线程的 CPU 亲和性
//     int result = pthread_setaffinity_np(currentThread, sizeof(cpu_set_t), &cpuset);
//     if (result != 0) {
//         qWarning() << "pthread_setaffinity_np failed:" << strerror(result);
//     } else {
//         qDebug() << "Thread affinity set to CPU" << cpu;
//     }
// }

void SurgicalRobotCamera::Operate(int index) 
{
	cv::Mat matIn;
	//LARGE_INTEGER liFrequency, BeginTime, EndTime;

	if (open(index))
	{
		qDebug() << "Camera open success!" << endl;
	}
	else {
		qDebug() << "Camera open failed!" << endl;
		return;
	}

	//QueryPerformanceFrequency((LARGE_INTEGER*)&liFrequency);

    //SetThreadAffinityMask(GetCurrentThread(), 1);
    // 在Linux下设置线程亲和性
    SurgicalRobotCommunication::setThreadAffinity(0);  // 将线程绑定到CPU 0

	while (1)
	{
		//QueryPerformanceCounter((LARGE_INTEGER*)&BeginTime);
		iCamera++;
		//qApp->processEvents();
		matIn = read();
		if (!matIn.empty()) {
		
			matNow = matIn;

			//QImage image = Mat2QImage(matIn);
			qComImage = Mat2QImage(matIn);
			//emit updateImage(image);
			emit updateImage();
		}
		else {
			std::cout << "read the frame is empty!" << std::endl;
		}
		//QueryPerformanceCounter((LARGE_INTEGER*)&EndTime);
		//qDebug() << liFrequency.QuadPart * 1000;
		//qDebug() << ((double)(EndTime.QuadPart - BeginTime.QuadPart) / (double)liFrequency.QuadPart) * 1000.0;
		

		cv::waitKey(50);
	}
}

/**
 * \brief   mat数据转换成Image数据.
 * 
 * \param mat  cv::mat data
 * \return     QImage data
 */
QImage SurgicalRobotCamera::Mat2QImage(cv::Mat const & mat)
{
	cv::Mat tmpMat;

	cvtColor(mat,tmpMat, CV_BGR2RGB);
	QImage image((const uchar*)tmpMat.data, tmpMat.cols, tmpMat.rows, tmpMat.step, QImage::Format_RGB888);
	image.bits();

	return image;
}

/**
 * \brief   QImage data转换到cv::mat data.
 * 
 * \param image QImage data
 * \return      cv::Mat data
 */
cv::Mat SurgicalRobotCamera::QImage2Mat(QImage const& image)
{
	cv::Mat tmpMat(image.height(), image.width(),CV_8UC3, (uchar*)image.bits(), image.bytesPerLine());
	cv::Mat mat;

	cvtColor(tmpMat, mat, CV_BGR2RGB);

	return mat;
}
